#Limits how fast the signal can change per scan cycle — useful for preventing actuator shock.

FUNCTION_BLOCK FB_RateLimiter
VAR_INPUT
    xEnable      : BOOL;
    rInput       : REAL;
    rMaxRiseRate : REAL := 10.0;   // Max units per second rising
    rMaxFallRate : REAL := 10.0;   // Max units per second falling
    rCycleTimeS  : REAL := 0.1;    // OB cycle time in seconds
END_VAR
VAR_OUTPUT
    rOutput : REAL;
END_VAR
VAR
    xFirst : BOOL := TRUE;
    rMaxStep : REAL;
    rMinStep : REAL;
    rDelta   : REAL;
END_VAR

IF NOT xEnable THEN
    xFirst  := TRUE;
    rOutput := rInput;
    RETURN;
END_IF;

IF xFirst THEN
    rOutput := rInput;
    xFirst  := FALSE;
    RETURN;
END_IF;

rMaxStep :=  rMaxRiseRate * rCycleTimeS;
rMinStep := -rMaxFallRate * rCycleTimeS;
rDelta   := rInput - rOutput;
rDelta   := MAX(MIN(rDelta, rMaxStep), rMinStep);
rOutput  := rOutput + rDelta;